﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Chromium;
using Chromium.Remote;
using Kugar.Core.BaseStruct;
using Kugar.Core.ExtMethod;

namespace Kugar.UI.RazorUI.RazorEngine
{
    public class ViewContext
    {
        public ViewContext(HttpContext context)
        {
            HttpContext = context;
        }

        public dynamic ViewBag { get; }=new ExpandoObject();

        public HttpContext HttpContext { get; }

        public Dictionary<string,object> ViewData { get; }=new Dictionary<string, object>();
    }

    public class HttpContext
    {
        public HttpContext(HttpRequest request)
        {
            Request = request;
        }

        public HttpRequest Request { get; }
    }

    public class HttpRequest
    {
        private CfxRequest _request = null;
        private Uri _requestUri = null;
        private Lazy<Dictionary<string, string>> _headers = null;
        private Lazy<IReadOnlyDictionary<string, string>> _query = null;
        private Lazy<Stream> _postData = null;
        private bool _hasPostData = false;

        public HttpRequest(CfxRequest request)
        {
            _request = request;

            if (request.PostData !=null && request.PostData.ElementCount>0)
            {
                _hasPostData = true;
                ContentLength = request.PostData.Elements.Sum(x => (int)x.BytesCount);
                _postData = new Lazy<Stream>(buildPostDataStream);
            }
            else
            {
                ContentLength=0;
            }

            

            var uri=new Uri(request.Url);

            _requestUri = uri;
            _headers = new Lazy<Dictionary<string, string>>(buildHeaders);
            _query=new Lazy<IReadOnlyDictionary<string, string>>(buildQuery);


            ContentType =
                request.GetHeaderMap().FirstOrDefault(x =>
                    x[0].CompareTo("content-type", true) || x[0].CompareTo("contenttype", true))?[1] ??
                "application/x-www-form-urlencoded";


        }

        public string Method => _request.Method;

        public string Host => _requestUri.Host;

        public string QueryString => _requestUri.Query;
        
        /// <summary>
        /// 内容长度
        /// </summary>
        public long ContentLength { get; }

        /// <summary>
        /// 当前Url
        /// </summary>
        public string Url => _request.Url;

        /// <summary>
        /// Http headers数据
        /// </summary>
        public IReadOnlyDictionary<string, string> Headers => _headers.Value;

        /// <summary>
        /// 查询字符串
        /// </summary>
        public IReadOnlyDictionary<string, string> Query => _query.Value;

        /// <summary>
        /// Request的输入流数据
        /// </summary>
        public Stream InputStream => _postData?.Value;

        public string ContentType { get; }

        private Dictionary<string, string> buildHeaders()
        {
            var dic=new Dictionary<string,string>(StringComparer.CurrentCultureIgnoreCase);

            var headers = _request.GetHeaderMap();

            foreach (var header in headers)
            {
                dic.Add(header[0],header[1]);
            }

            return dic;
        }

        private IReadOnlyDictionary<string, string> buildQuery()
        {
            var q = _requestUri.GetQueryInfo();

            return q;
        }

        private Stream buildPostDataStream()
        {
            if (_request.PostData.ElementCount>0 || !_request.Method.CompareTo("post",true))
            {
                return null;
            }

            foreach (var element in _request.PostData.Elements)
            {
                var size = element.GetBytes(element.BytesCount, element.NativePtr);

                var buff = new byte[element.BytesCount];

                Marshal.Copy(element.NativePtr, buff, 0,(int)size);

                return new ByteStream(buff);
            }

            return null;
        }

    }

    public class HttpResponse
    {

    }
}
